#ifndef ___fuse_mkdir
#define ___fuse_mkdir 1

#ifndef FUSE_USE_VERSION
#define FUSE_USE_VERSION 28
#endif

#include <stdio.h>
#include <stdlib.h>
#include "mtlib.c"
#include <fuse.h>
#include <fcntl.h>
#include <errno.h>
#include "logging.c"

struct datosCrearDir {
    char * path;
    char estado;
};

//Prototipos
int fuse_mkdir(const char *, mode_t);
void ___fuse_procesar_mensaje_mkdir(unsigned char, mti_mensaje, struct datosCrearDir *);

//CREAR UN DIRECTORIO
int fuse_mkdir(const char * path, mode_t modo) {

    mti_mensaje datosMensaje;
    int resultado;
    short permisos;
    unsigned char centro_mkdir = 0;
    unsigned int descriptorConexion;
    struct datosCrearDir datos;

        datos.estado = 0;
        datos.path = path;

        if ((modo &16384) == S_IFDIR)  {
            permisos = (modo) &0511; //obtengo con chmod los ultimos 9 bits de permisos

        } else
            return -ENOTDIR;

        while (!centro_mkdir)
            centro_mkdir = mtf_obtener_descriptor(1024);

        descriptorConexion = mtf_conectar(centro_mkdir, MTP_INTERNO, centro_fat);

        if (descriptorConexion == 0) {
            mtf_liberar_descriptor(centro_mkdir);
            return -EAGAIN;
        }

        resultado = mtf_enviar_mensaje(centro_mkdir, descriptorConexion, MTE_CREAR_DIRECTORIO, (char *) datos.path, (int) permisos);

        if (resultado == 0) {
            mtf_desconectar(centro_mkdir, descriptorConexion);
            mtf_liberar_descriptor(centro_mkdir);
            return -EAGAIN;
        }

        while (!datos.estado) {

            if (!mtf_recibir_mensajes(centro_mkdir)) continue;

            datosMensaje = mtf_siguiente_mensaje(centro_mkdir);
            ___fuse_procesar_mensaje_mkdir(centro_mkdir, datosMensaje, &datos);
            mtf_descartar_mensaje(centro_mkdir, datosMensaje.codigo);

        }

        mtf_desconectar(centro_mkdir, descriptorConexion); //desconecto la conexion del centro de mensajes
        mtf_liberar_descriptor(centro_mkdir); //libero centro de mensajes con sus datos y conexiones

        switch (datos.estado) {

        case 1:
            return -ENOENT; //path no existe
        case 2:
            return -EEXIST; //path ya existe
        case 3:
            return -EACCES; //disco lleno
        default:
            return EXIT_SUCCESS;
        }
}

void ___fuse_procesar_mensaje_mkdir(unsigned char centro_mkdir, mti_mensaje datosMensaje, struct datosCrearDir * datosCrear) {

    if (datosMensaje.categoria != MTA_MENSAJE) return;

      switch (datosMensaje.tipo) {

        case MTE_NULL:

          mtf_enviar_mensaje(centro_mkdir, datosMensaje.remitente, MTR_NULL);

        break;

        case MTR_NULL: case MTQ_MENSAJE_NO_VALIDO:

        break;

        //MENSAJES PARA CREAR DIRECTORIO
        case MTR_DIRECTORIO_CREADO:
        {
            char * nombreDirectorio = NULL;

                mtf_obtener_datos(centro_mkdir, datosMensaje.codigo,(char **) &nombreDirectorio);
                log_registrar(descArch, "FUSE", LOG_INFO, "Se pudo crear el directorio %s \n", nombreDirectorio);
                free(nombreDirectorio);
        }
        break;

        case MTR_DIRECTORIO_NO_CREO:
        {
            char * nombreDirectorio = NULL;
            char motivo;

                mtf_obtener_datos(centro_mkdir, datosMensaje.codigo,(char **) &nombreDirectorio,(char *) &motivo);

                datosCrear -> estado = motivo;
                log_registrar(descArch, "FUSE", LOG_WARN, "No se pudo crear el directorio %s \n", nombreDirectorio);
                free(nombreDirectorio);
        }
        break;

        default:

              mtf_enviar_mensaje(centro_mkdir, datosMensaje.remitente, MTQ_MENSAJE_NO_VALIDO);

        break;

     }
}

#endif

